#ifndef _PLATFORM_H_CSEAPI_
#define _PLATFORM_H_CSEAPI_

#include "setup.h"

#ifdef _DEBUG
  #ifndef DEBUG
    #define DEBUG
  #endif
#endif

#ifdef DEBUG
  #ifndef _DEBUG
    #define _DEBUG
  #endif
#endif

#ifdef WINCE
  #undef  WINVER
  #define WINVER _WIN32_WCE

  #ifndef VC_EXTRALEAN
    #define VC_EXTRALEAN
  #endif

  #include <ceconfig.h>
  #if defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)
    #define SHELL_AYGSHELL
  #endif

  #if defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP)
    #ifndef _DEVICE_RESOLUTION_AWARE
      #define _DEVICE_RESOLUTION_AWARE
    #endif
  #endif

  #ifdef _DEVICE_RESOLUTION_AWARE
    #include "DeviceResolutionAware.h"
  #endif

  #include <aygshell.h>
  #pragma comment(lib, "aygshell.lib") 

  #if (_WIN32_WCE < 0x500) && ( defined(WIN32_PLATFORM_PSPC) || defined(WIN32_PLATFORM_WFSP) )
    #pragma comment(lib, "ccrtrtti.lib")
    #ifdef _X86_
        #if defined(_DEBUG)
            #pragma comment(lib, "libcmtx86d.lib")
        #else
            #pragma comment(lib, "libcmtx86.lib")
        #endif
    #endif
  #endif

  #include <altcecrt.h>

  #undef  CSE_USE_UNICODE
  #define CSE_USE_UNICODE          1   // WinCE only support unicode
#endif

#include <limits.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>

#define CSE_USE_PLATFORM           1
#include "CseTypes.h"

#if defined(__VISUALC__)
  #pragma warning(disable: 4996)
#endif

#if defined(__VISUALC__) || defined(__MINGW32__)
  #define CSE_STDCALL              __stdcall
  #define CSE_CDECL                __cdecl
  #define CSE_EXPORT               __declspec(dllexport)
  #define CSE_IMPORT               __declspec(dllimport)

  #define CseLongLongFmtSpec       _T("I64")
  #define CsePathSpliter           _T('\\')
#elif defined(__GNUC__)
  #define CSE_STDCALL              __attribute__((stdcall))
  #define CSE_CDECL                __attribute__((cdecl))
  #if __GNUC__ >= 4
    #define CSE_EXPORT             __attribute__((visibility("default")))
    #define CSE_IMPORT
  #else
    #define CSE_EXPORT             __attribute__((dllexport))
    #define CSE_IMPORT             __attribute__((dllimport))
  #endif
  
  #define CseLongLongFmtSpec       _T("ll")  // used in linux
  #define CsePathSpliter           _T('/')
#else
  #error "Compiler not support yet!"
#endif

#ifdef CSEAPI_EXPORTS              // Export CSE kernel API
  #define CSE_IMPEXP_IN            CSE_EXPORT
#elif CSE_STATIC_LINK              // Static link CSE kernel
  #define CSE_IMPEXP_IN
#else                              // Import CSE kernel from DLL
  #define CSE_IMPEXP_IN            CSE_IMPORT
#endif
#define CSE_IMPEXP_OUT             CSE_EXPORT

#undef  CHECK_MSG
#undef  CHECK_TRUE
#define CHECK_MSG(b,desc)          (b? 0: Cse_AssertMsg(0,desc))
#define CHECK_TRUE(b)              (b? 0: Cse_AssertMsg2(0,__LINE__,_T(__FILE__)))

#undef WAIT_TO_DO
#define WAIT_TO_DO()               throw Cse_WaitToDo(__LINE__,_T(__FILE__))

#undef ASSERT_MSG
#undef ASSERT_TRUE
#ifdef _DEBUG
  #define ASSERT_MSG(b,desc)       Cse_AssertMsg(b,desc)
  #define ASSERT_TRUE(b)           CHECK_TRUE(b)
#else
  #define ASSERT_MSG
  #define ASSERT_TRUE
#endif

#if CSE_USE_ERR_LOG
  #if defined(_UNICODE)
    #define LOG_MSG                wprintf
  #else
    #define LOG_MSG                printf
  #endif
#else
  #define LOG_MSG
#endif

#ifdef _DEBUG
  #define STATIC
  #define LOG_DBG_MSG              LOG_MSG
#else
  #define STATIC                   static
  #define LOG_DBG_MSG
#endif

#define CSE_PRINT                  CsePrint
#define APP_ARGUMENTS()            CseRegister->get(_T("KERNEL/ARGS"))

// following is supported by C99 standard
#ifdef _UNICODE
  #define PRINTF                   wprintf
  #define STRCPY                   wcscpy
  #define STRNCPY                  wcsncpy
  #define STRSTR                   wcsstr
  #define STRCMP                   wcscmp
  #define SPRINTF                  swprintf
  #define VSPRINTF                 vswprintf
  #define STRLEN                   wcslen
  #define STRCAT                   wcscat
  #define SCANF                    wscanf
  #define SSCANF                   swscanf
  #define GETCHAR                  getwchar
  
  #define FGETS                    fgetws
  #define FSCANF                   fwscanf
#else
  #define PRINTF                   printf
  #define STRCPY                   strcpy
  #define STRNCPY                  strncpy
  #define STRSTR                   strstr
  #define STRCMP                   strcmp
  #define SPRINTF                  sprintf
  #define VSPRINTF                 vsprintf
  #define STRLEN                   strlen
  #define STRCAT                   strcat
  #define SCANF                    scanf
  #define SSCANF                   sscanf
  #define GETCHAR                  getchar
  
  #define FGETS                    fgets
  #define FSCANF                   fscanf
#endif

class TCseException;  // forward declare
extern CSE_IMPEXP_IN TBool Cse_AssertMsg(int expr, const TXchar *msg);
extern CSE_IMPEXP_IN TBool Cse_AssertMsg2(int expr, int iLine, const TXchar *sFile);
extern CSE_IMPEXP_IN TCseException Cse_WaitToDo(int line, const TXchar *sFile);

extern CSE_IMPEXP_IN TInt32 READ_FLAG(TInt32 iFlag, int iOffset, int n);
extern CSE_IMPEXP_IN TInt32 MAKE_FLAG(TInt32 iFlag, TInt32 iValue, int iOffset, int n);

#define CUT_FROM                   20051206  // The date CSE V1 first released

#endif
